/*
*  Copyright (c) 2006-2020, Chukie
*
*  SPDX-License-Identifier: Apache-2.0
*
*  @file     :
*
*  @brief    :
*  Website   : https://gitee.com/zcj20080882
*
*
*  Change Logs:
*  Date           Author          Notes
*  2021-02-18     zhaocj       The first version
*/
/* Includes -----------------------------------------------------------------*/
#include <stdlib.h>
#include "sms_pdu.h"
#include "system.h"
#include "config.h"
#include "cellular.h"
#include "at_client.h"
#include "cellular_sms.h"

#define DBG_TAG "[SMS]"
#define DBG_LVL DBG_LOG
#include <cellular_log.h>
/* Private typedef ----------------------------------------------------------*/
/* Private define -----------------------------------------------------------*/
#ifndef TICK_PER_SECOND
    #define TICK_PER_SECOND             1000
#endif /*TICK_PER_SECOND*/
#define LONG_SMS_HEADER                 6
#define GSM_SMS_MAX_LEN                 160
#define GSM_LONG_SMS_MAX_LEN            (GSM_SMS_MAX_LEN - LONG_SMS_HEADER - 1)  
#define UCS_SMS_MAX_LEN                 140
#define UCS_LONG_SMS_MAX_LEN            (UCS_SMS_MAX_LEN - LONG_SMS_HEADER)          
#define SMS_MAX_BUFF_SIZE               513
/* Private variables --------------------------------------------------------*/
/* Extern variables ---------------------------------------------------------*/
/* Private function prototypes ----------------------------------------------*/
/* Public function prototypes -----------------------------------------------*/
int gsm_calc_sms_send(uint16_t length)
{
    if (length > GSM_SMS_MAX_LEN)
    {
        if (length % GSM_LONG_SMS_MAX_LEN)
        {
            return length / GSM_LONG_SMS_MAX_LEN + 1;
        }
        return length / GSM_LONG_SMS_MAX_LEN;
    }
    return 1;
}

int ucs_calc_sms_send(uint16_t length)
{
    if (length > UCS_SMS_MAX_LEN)
    {
        if (length % UCS_LONG_SMS_MAX_LEN)
        {
            return length / UCS_LONG_SMS_MAX_LEN + 1;
        }
        return length / UCS_LONG_SMS_MAX_LEN;
    }
    return 1;
}

void number_2_sca_addr(const char *number, char *sca_addr, uint16_t size)
{
    uint8_t  tmp = 0;
    uint16_t cnt = 0;
    uint16_t len = strlen(number);
    if (len > size - 1)
    {
        return;
    }
    for (cnt = 0; (cnt + 2 < len); )
    {
        tmp = number[cnt++];
        *sca_addr++ = number[cnt++];
        *sca_addr++ = tmp;
    }
    if (cnt < len)
    {
        *sca_addr++ = 'F';
        *sca_addr++ = number[cnt];
    }
    *sca_addr = '\0';
    return;
}

int pdu_addr_packet(const char* number, char *buff, uint16_t size, int is_csca)
{
    int ret = 0;
    uint8_t type = 0;
    uint16_t sca_len = 0;
    uint16_t addr_len = 0;
    memset(buff, 0, size);
    if (number && strlen(number) && size >= (strlen(number + 4)))
    {
        if ('+' == number[0])
        {
            number++;
            type = 0x91;            
        }
        else
        {
            if ('8' == number[0] && '6' == number[1])
            {
                type = 0x91;
            }
            else
            {
                type = 0x81;
            }            
        }
        addr_len = strlen(number);
        sca_len  = addr_len % 2 ? addr_len / 2 + 1 : addr_len / 2;
        sca_len += 1;
        ret = snprintf(buff, size, "%02X%02X", (is_csca ? sca_len : addr_len), type);
        number_2_sca_addr(number, (char *)(buff + ret), size - ret);
        ret = strlen(buff);
    } 
    else
    {
        memcpy(buff, "00", sizeof("00"));
        ret = strlen(buff);
    }
    return ret;
}

int pack_tpdu(char *buff, int size, const char *receiver, int report, int encode, 
    char *content, int length, int is_long_sms, int send_all, int send_idx)
{
    int len = 0;
    int udl = length;
    uint8_t octet   = 0;
    uint8_t fillbit = 0;
    if (PDU_DCS_GSM == encode)
    {
        if (is_long_sms)
        {
            fillbit = content[0];
            fillbit = fillbit << 1;
            length  = ASCII2GSM7bit((uint8_t *)&content[1], length - 1, FALSE);
            content ++;
        }
        else
        {
            length  = ASCII2GSM7bit((uint8_t *)&content[0], length - 0, FALSE);
        }
    }
    if (is_long_sms)
    {
        octet |= (1 << 6);
    }
    if (report)
    {
        octet |= (1 << 5);
    }
    octet |= (1 << 0);
    len += snprintf(buff, size, "%02X", octet);
    //MR
    len += snprintf(buff + len, size - len, "00");
    //DA
    len += pdu_addr_packet(receiver, buff + len, size - len, FALSE);
    //PID
    len += snprintf(buff + len, size - len, "00");
    //DCS
    len += snprintf(buff + len, size - len, "%02X", encode);
    if (is_long_sms)
    {
        udl += LONG_SMS_HEADER;
        len += snprintf(buff + len, size - len, "%02X", PDU_DCS_GSM == encode ? udl + 1 : udl);
        len += snprintf(buff + len, size - len, "050003FF%02X%02X", send_all, send_idx);
        if (PDU_DCS_GSM == encode)
        {
            len += snprintf(buff + len, size - len, "%02X", fillbit);
        }
    }
    else
    {
        len += snprintf(buff + len, size - len, "%02X", udl);
    }
    octet = 0;
    while (len < size && octet < length)
    {
        len += snprintf(buff + len, size - len, "%02X", content[octet++]);      
    }
    return strlen(buff);
}
/* End of file****************************************************************/
